/**
 * @class
 * @param {Storage} func - localStorage | sessionStorage
 */
class DefineStorage<T extends Storage = Storage> {
  /** 缓存函数 */
  private readonly func: T

  /**
   * @constructs
   */
  constructor(func: T) {
    this.func = func
  }

  /**
   * @function
   * @description 获取本地缓存
   * @param prop {string} prop
   * @param prop {boolean} encode
   * @returns {string | null}
   */
  get(this: DefineStorage, prop: string, encode = false): string | null {
    let value = this.func.getItem(prop)
    try {
      if (!value) return null
      if (encode) {
        value = window.atob(value)
      }
      value = decodeURIComponent(value)
      return JSON.parse(value)
    } catch (e) {
      return decodeURIComponent(value!)
    }
  }

  /**
   * @function
   * @description 设置本地缓存
   * @param {string} prop
   * @param {string} value
   * @param {boolean} encode
   * @returns {void}
   */
  set(this: DefineStorage, prop: string, value: any, encode = false): void {
    try {
      value = encodeURIComponent(JSON.stringify(value))
      value = encode ? window.btoa(value) : value
      this.func.setItem(prop, value)
    } catch (e) {
      //
    }
  }

  /**
   * @function
   * @description 删除本地缓存
   * @param {string[]}
   * @returns {void}
   */
  remove(this: DefineStorage, ...props: string[]): void {
    props.forEach((item) => this.func.removeItem(item))
  }
}

export const Local = new DefineStorage(localStorage)
export const Session = new DefineStorage(sessionStorage)
